﻿using Rsd.Dudu;
using Rsd.Dudu.BizModel;
using Rsd.Dudu.Web;
using Rsd.Dudu.Web.Core;
using Rsd.Dudu.Web.MVC;

using Rsd.Faith.Core;
using Rsd.Faith.Fiscal.Core;
using Rsd.Faith.Models;
using Rsd.Faith.Report.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;

namespace Rsd.Faith.Report.Controllers
{
   
    /// <summary>
    /// RWebService 的摘要说明
    /// </summary>

    public class ReportController : Rsd.Faith.Core.FaithController
    {
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [ApiService("Index", false)]
        public override object Index()
        { 
            return base.Index();
        }

        /// <summary>
        /// 资金概况统计
        /// </summary>
        /// <returns></returns>
        [PramaRule("start", "开始日期(start)", 6, 8, false)]
        [PramaRule("end", "结束日期(end)", 6, 8, false)]
        [ApiService("资金概况统计", true)]
        public object Global()
        {
            var list = MyType.GetType<Rsd.Faith.Models.ReportZiJinZongZhangModel>().GetObjects(null,obj=>obj.SuoShuQi, Dudu.DBServices.SortType.ASC);
          
            var total_jiao_cun = 0.00M;
            var list_nian_yue = new List<string>();
            var list_jiao_cun = new List<decimal>();
            var list_jiao_cun_zong_e = new List<decimal>();
            var list_shi_yong = new List<decimal>();
            foreach (var r in list)
            {
                var _jin_e = r.JiaoCunJinE_ZZ;

                list_nian_yue.Add(r.SuoShuQi);
                list_shi_yong.Add(r.ShiYongJinE_ZZ);
                list_jiao_cun.Add(_jin_e);
                total_jiao_cun += _jin_e;
                list_jiao_cun_zong_e.Add(total_jiao_cun);
            }


            return new
            {
                NianYue = list_nian_yue.ToArray(),
                JiaoCun = list_jiao_cun.ToArray(),
                ShiYong = list_shi_yong.ToArray(),
                ZongE = list_jiao_cun_zong_e.ToArray()
            };
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="suoShuQi"></param>
        /// <returns></returns>
        [PramaRule("suoShuQi", "所属期(suoShuQi)", typeof(string))]
        [ApiService("新建账目周期", true)]
        public object NewPeriod(string suoShuQi)
        {
            var msg = "";
            if (!this.CheckSuoShuQi(suoShuQi, out msg))
            {
                return new ErrorResult(-1, msg, null);
            }

            MyType.InitialTable<BankFenHuShouYiBiaoModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi); ;
            MyType.InitialTable<ReportFenHuZhangMuModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi);

            var zhang = this.GetObject<ReportZiJinZongZhangModel>(obj => obj.SuoShuQi == suoShuQi);
            if (zhang == null)
            {
                zhang = new ReportZiJinZongZhangModel();
                zhang.SuoShuQi = suoShuQi;
                zhang.KaiShiRiQi = DateTime.Parse(suoShuQi + "-01-01");
                zhang.JieShuRiQi = DateTime.Parse(suoShuQi + "-12-31");
                zhang.SetState(ObjectStateType.New);
                this.SaveObject(zhang);
            }
            return zhang;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="suoShuQi"></param>
        /// <returns></returns>
        [PramaRule("suoShuQi", "所属期(suoShuQi)", typeof(string))]
        [ApiService("设置所属期状态为记账中", true)]
        public object SetPeriodStart(string suoShuQi)
        {
            var msg = "";
            if (!this.CheckSuoShuQi(suoShuQi, out msg))
            {
                return new ErrorResult(-1, msg, null);
            }

            MyType.InitialTable<BankFenHuShouYiBiaoModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi); ;
            MyType.InitialTable<ReportFenHuZhangMuModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi);

            var zhang = this.GetObject<ReportZiJinZongZhangModel>(obj => obj.SuoShuQi == suoShuQi);
            if (zhang == null)
            {
                return new ErrorResult<ErrorCodesType>(ErrorCodesType.R10003, suoShuQi); ;
            }

            if (zhang.ZhuangTai == ZhangMuZhuangTai.None)
            {
                zhang.ZhuangTai = ZhangMuZhuangTai.JZZ;
                zhang.SetState(ObjectStateType.Update);
                this.SaveObject(zhang);
            }
           
            return zhang;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="suoShuQi"></param>
        /// <returns></returns>
        [PramaRule("suoShuQi", "所属期(suoShuQi)", typeof(string))]
        [ApiService("设置所属期状态为已扎帐", true)]
        public object SetPeriodEnd(string suoShuQi)
        {
            var msg = "";
            if (!this.CheckSuoShuQi(suoShuQi, out msg))
            {
                return new ErrorResult(-1, msg, null);
            }

            MyType.InitialTable<BankFenHuShouYiBiaoModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi); ;
            MyType.InitialTable<ReportFenHuZhangMuModel>(Dudu.DBServices.TableExistOperationType.AlterAndDropColumn, suoShuQi);

            var zhang = this.GetObject<ReportZiJinZongZhangModel>(obj => obj.SuoShuQi == suoShuQi);
            if (zhang == null)
            {
                return new ErrorResult<ErrorCodesType>(ErrorCodesType.R10003, suoShuQi);  
            }
            if (zhang.JieShuRiQi.AddHours(24) > DateTime.Now)
            {
                return new ErrorResult<ErrorCodesType>(ErrorCodesType.R10004, zhang.JieShuRiQi.ToString("yyyy-MM-dd")); 
            }
            if (zhang.ZhuangTai == ZhangMuZhuangTai.JZZ)
            {
                zhang.ZhuangTai = ZhangMuZhuangTai.YHS;
                zhang.SetState(ObjectStateType.Update);
                this.SaveObject(zhang);
            }

            return zhang;
        }

        /// <summary>
        /// 资金总账核算
        /// </summary>
        /// <param name="reportService"></param>
        /// <param name="suoShuQi"></param>
        /// <returns></returns>
        [PramaRule("suoShuQi", "所属期(suoShuQi)", typeof(string))]
        [ApiService("资金总账核算", true)]
        [ApiServiceBindIP(true, "127.0.0.1", "101.132.143.133")]
        public object HeSuanZiJinZongZhang([Service]IReportService reportService, string suoShuQi)
        {
            var msg = "";
            if (!this.CheckSuoShuQi(suoShuQi, out msg))
            {
                return new ErrorResult(-1, msg, null);
            }
           
            var zongZhang = this.GetObject<ReportZiJinZongZhangModel>(obj => obj.SuoShuQi == suoShuQi);
          
           
            return reportService.ZiJinZongZhangHeSuan(zongZhang);
        }

        /// <summary>
        /// 小区总账核算
        /// </summary>
        /// <param name="reportService"></param>
        /// <param name="suoShuQi"></param>
        /// <param name="xiaoQuBianHao"></param>
        /// <returns></returns>
        [PramaRule("xiaoQuBianHao", "小区编号(xiaoQuBianHao)")]
        [ApiService("小区总账核算", true)]
        [ApiServiceBindIP(true, "127.0.0.1", "101.132.143.133")]
        public object HeSuanXiaoQuZongZhang([Service]IReportService reportService, [Service] IBookService bookService, string xiaoQuBianHao)
        {
            var zhang = this.GetObject<BookXiaoQuZongZhangModel>(obj => obj.XiaoQuBianHao == xiaoQuBianHao);
            if (zhang == null)
            {
                var xiaoQu = this.GetObject<InfoXiaoQuWuYeBiaoModel>(obj => obj.BianHao == xiaoQuBianHao);
                if (xiaoQu == null)
                {
                    return new ErrorResult(-1, "小区(编号：" + xiaoQuBianHao + ")不存在", null);

                }
                var arr = MyType.GetType<FiscalPiaoJuXinXiBiaoModel>().GetObjects(obj => obj.XiaoQuBianHao == xiaoQuBianHao, obj => obj.JiaoNaRiQi, Dudu.DBServices.SortType.ASC);

                if (arr.Length > 0)
                {
                    zhang = bookService.NewXiaoQuAccount(xiaoQuBianHao, xiaoQu.MingCheng, arr[0].JiaoNaRiQi);
                }
            }
            if (zhang==null)
            {
                return new ErrorResult(-1, "小区(编号：" + xiaoQuBianHao + ")账户不存在", null);
            }

            return reportService.XiaoQuZongZhangHeSuan(zhang);
        }

        /// <summary>
        /// 小区楼栋明细核算 所有属期
        /// </summary>
        /// <param name="fiscalService"></param>
        /// <param name="xiaoQuBianHao"></param>
        /// <returns></returns>
        [PramaRule("xiaoQuBianHao", "小区编号(xiaoQuBianHao)")]
        [PramaRule("maxCount", "最大并发线程数(maxCount)", 1.00, 20.00, false, 2)]
        [ApiService("小区楼栋明细核算", true)]
        [ApiServiceBindIP(true, "127.0.0.1", "101.132.143.133")]
        public object HeSuanLouDongZhang([Service]IReportService reportService,  string xiaoQuBianHao, int maxCount)
        {
            //加大超时时间 
            this.Context.Server.ScriptTimeout = 3600;
           
            var list = this.GetObjects<BookLouDongMingXiZhangModel>(obj => obj.XiaoQuBianHao == xiaoQuBianHao);

            var subList = new List<BookLouDongMingXiZhangModel>[maxCount];
            for (var i = 0; i < maxCount; i++)
            {
                subList[i] = new List<BookLouDongMingXiZhangModel>();
            }
            for (var i = 0; i < list.Length; i++)
            {
                subList[i % maxCount].Add(list[i]);
            }
            var taskList = new List<Task>();

            foreach (var sub in subList)
            {
                if (sub == null || sub.Count == 0)
                {
                    continue;
                }
                var _task = new Task(() =>
                {
                    foreach (var zhang in sub)
                    {
                        reportService.LouDongZhangHeSuan(zhang);
                    }
                });
                taskList.Add(_task);
                _task.Start();

            }
            foreach (var _task in taskList)
            {
                if (_task.Status == TaskStatus.Running)
                {
                    _task.Wait();
                }
            }
            return list.Length;

        }


        /// <summary>
        /// 小区楼栋单元明细核算 所有明细 所有属期
        /// </summary>
        /// <param name="fiscalService"></param>
        /// <param name="suoShuQi"></param>
        /// <param name="xiaoQuBianHao"></param>
        /// <returns></returns>
        [PramaRule("xiaoQuBianHao", "小区编号(xiaoQuBianHao)")]
        [PramaRule("maxCount", "最大并发线程数(maxCount)", 1.00, 20.00, false, 4)]
        [ApiService("小区楼栋单元明细账目核算", true)]
        [ApiServiceBindIP(true, "127.0.0.1", "101.132.143.133")]
        public object HeSuanDanYuanZhang([Service]IReportService reportService,  string xiaoQuBianHao, int maxCount)
        {
            //加大超时时间 
            this.Context.Server.ScriptTimeout = 3600;
            var rs = 0;

            var list = this.GetObjects<BookDanYuanMingXiZhangModel>(obj => obj.XiaoQuBianHao == xiaoQuBianHao);
            var subList = new List<BookDanYuanMingXiZhangModel>[maxCount];
            for (var i = 0; i < maxCount; i++)
            {
                subList[i] = new List<BookDanYuanMingXiZhangModel>();
            }
            for (var i = 0; i < list.Length; i++)
            {
                subList[i % maxCount].Add(list[i]);
            }
            var taskList = new List<Task>();

            foreach (var sub in subList)
            {
                if (sub == null || sub.Count == 0)
                {
                    continue;
                }
                var _task = new Task(() =>
                {
                    foreach (var zhang in sub)
                    {
                        reportService.DanYuanZhangHeSuan(zhang);
                    }
                });
                taskList.Add(_task);
                _task.Start();

            }
            foreach (var _task in taskList)
            {
                if (_task.Status == TaskStatus.Running)
                {
                    _task.Wait();
                }
            }

            return rs;
        }


        /// <summary>
        /// 核算小区所有分户账户所有属期
        /// </summary>
        /// <param name="reportService"></param>
        /// <param name="xiaoQuBianHao"></param>
        /// <param name="maxCount"></param>
        /// <returns></returns>
        [PramaRule("xiaoQuBianHao", "小区编号(xiaoQuBianHao)", typeof(string))]
        [PramaRule("maxCount", "最大并发线程数(maxCount)", 1.00, 20.00, false, 6)]
        [ApiService("核算小区所有分户账户所有属期", false)]
        [ApiServiceBindIP(true, "127.0.0.1", "101.132.143.133")]
        public object HeSuanFenHuZhang([Service]IReportService reportService, string xiaoQuBianHao, int maxCount)
        {
            //加大超时时间 
            this.Context.Server.ScriptTimeout = 3600;

            var list = MyType.GetObjects<BookFenHuZhangModel>(obj => obj.XiaoQuBianHao == xiaoQuBianHao);
            var subList = new List<BookFenHuZhangModel>[maxCount];
            for (var i = 0; i < maxCount; i++)
            {
                subList[i] = new List<BookFenHuZhangModel>();
            }
            for (var i = 0; i < list.Length; i++)
            {
                subList[i % maxCount].Add(list[i]);
            }
            var taskList = new List<Task>();
            foreach (var sub in subList)
            {
                if (sub == null || sub.Count == 0)
                {
                    continue;
                }
                var _task = new Task(() =>
                {
                    foreach (var zhang in sub)
                    {
                        //期内核算
                        reportService.FenHuHeSuan(zhang);
                        //上 下期 结转 扎帐
                        reportService.FenHuZhaZhang(zhang);
                    }
                });
                taskList.Add(_task);
                _task.Start();

            }
            foreach (var _task in taskList)
            {
                if (_task.Status == TaskStatus.Running)
                {
                    _task.Wait();
                } 
            }
            return list.Length;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reportService"></param>
        /// <returns></returns>
        [ApiService("核算增值账户所有属期", false)]
        public object HeSuanZengZhi([Service]IReportService reportService)
        {
            return reportService.ZengZhiHeSuan();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="reportService"></param>
        /// <param name="suoshuqi"></param>
        /// <returns></returns>
        [PramaRule("suoshuqi", "所属期(suoshuqi)", typeof(string))]
        [ApiService("生成催缴单", false)]
        public object ShenChengCuiJiao([Service] IReportService reportService,string suoshuqi)
        {
            return reportService.ShenChengCuiJiao(suoshuqi);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xiaoQuBianHao"></param>
        /// <param name="louDongHao"></param>
        /// <returns></returns>
        [PramaRule("xiaoQuBianHao", "小区编号(xiaoQuBianHao)")]
        [PramaRule("louDongHao", "楼栋号(louDongHao)", 1,20,false,"")]
        [ApiService("发票导出", true)]
        public object ExportExcel(string xiaoQuBianHao, string louDongHao)
        {
            var xiaoqu = MyType.GetObject<Rsd.Faith.Models.InfoXiaoQuWuYeBiaoModel>(obj => obj.BianHao == xiaoQuBianHao);
            if (xiaoqu == null)
            {
                return new ErrorResult("", "小区不存在", null);
            }
            var left = MyType.GetReportService<Rsd.Faith.Models.InfoFangWuXinXiBiaoModel>();
            var right = MyType.GetReportService <Rsd.Faith.Models.FiscalPiaoJuXinXiBiaoModel>();

             left.Select(obj => obj.BianHao, "房屋编号")
                  .Select(obj => obj.YeZhuXingMing, "业主姓名")
                 .Select(obj => obj.XiaoQuBianHao, "小区编号")
                 .Select(obj => obj.LouDongHao, "楼栋")
                 .Select(obj => obj.DanYuanHao, "单元")
                 .Select(obj => obj.ShiHao, "室")
                 .Select(obj => obj.JianZhuMianJi, "建筑面积");
            if (string.IsNullOrEmpty(louDongHao))
            {
                left.Where(obj => obj.XiaoQuBianHao == xiaoQuBianHao);
            }
            else
            {
                left.Where(obj => obj.XiaoQuBianHao == xiaoQuBianHao && obj.LouDongHao == louDongHao);
            }
            var leftView = left.View("A");

            var rightView = right.Select(obj => obj.FangWuDaiMa, "房屋代码")
                .Select(obj => obj.FaPiaoBianHao,"发票号码")
                .Select(obj => obj.ShiJiaoJinE, "实缴金额")
                .Select(obj => obj.YingJiaoJinE,"应缴金额")
                .Select(obj => obj.JiaoNaRiQi,"缴纳日期").View("B");

            var report = MyType.GetReportService();
            var dt = report.Select("房屋编号", "业主姓名", "楼栋", "单元", "室", "建筑面积", "发票号码", "实缴金额", "应缴金额", "缴纳日期")
                .Join(leftView, Dudu.DBServices.JoinType.Left, rightView, "C")
                .On("房屋编号", Dudu.Core.OperatorType.Equals, "房屋代码")
                .OrderBy("楼栋", Dudu.DBServices.SortType.ASC)
                .OrderBy("单元", Dudu.DBServices.SortType.ASC)
                .OrderBy("室", Dudu.DBServices.SortType.ASC)
                .Execute();

            if (dt == null)
            {
                return new ErrorResult("","没有可下载数据",null);
            }
            this.Context.Response.WriteExcel(xiaoqu.MingCheng + "["+ xiaoqu.BianHao+ "](" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + ")",new Dudu.Helpers.ExcelSheet() { Title = xiaoqu.MingCheng + (string.IsNullOrEmpty(louDongHao) ? "" : ("(" + louDongHao + "栋)")), Data = dt });

            return new DataResult(true, "下载成功");
        }

    }
}